package com.controller;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bean.dto.Dto;
import com.bean.pojo.*;
import com.bean.vo.order.ItripAddHotelOrderVO;
import com.config.AlipayConfig;
import com.mysql.jdbc.Wrapper;
import com.pojo.Code;
import com.service.*;
import com.util.DtoUtil;
import com.util.MD5;
import com.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@RestController
public class AlipayController2 {

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private IItripHotelTempStoreService iItripHotelTempStoreService;
    @Autowired
    private IItripTradeEndsService iItripTradeEndsService;
    @Autowired
    private IItripUserService itripUserService;
    @Autowired
    private IItripHotelOrderService iItripHotelOrderService;
    @Autowired
    private IItripHotelRoomService iItripHotelRoomService;

    @PostMapping("/api/alipay/createOrder")
    public @ResponseBody
    Object pay(@RequestBody String WIDout_trade_no, HttpServletRequest request) {
        System.out.println(">>>进入支付");
        System.out.println(WIDout_trade_no);

        //100000 : token失效，请重登录
        //获取token字符串
        String istoken = request.getHeader("token");
        String string = null;
        try {
            string = redisUtil.getString(istoken);
        } catch (Exception e) {
            return DtoUtil.returnError("100000", "token失效，请重登录", "");
        }
        System.out.println(string);
        if (string == null) {
            return DtoUtil.returnError("100000", "token失效，请重登录", "");
        }

        //String转实体
        ItripHotelOrder itripHotelOrder = JSONObject.parseObject(WIDout_trade_no, ItripHotelOrder.class);
        List<ItripUserLinkUser> linkUser = JSONObject.parseObject(WIDout_trade_no, ItripAddHotelOrderVO.class).getLinkUser();
        System.out.println(itripHotelOrder);
        //查询库存是否足够
        QueryWrapper<ItripHotelTempStore> wrapper = new QueryWrapper<>();
        wrapper.eq(itripHotelOrder.getHotelId() != null, "hotelId", itripHotelOrder.getHotelId());
        wrapper.eq(itripHotelOrder.getRoomId() != null, "roomId", itripHotelOrder.getRoomId());
        wrapper.ge(itripHotelOrder.getCheckInDate() != null, "recordDate", itripHotelOrder.getCheckInDate());
        wrapper.le(itripHotelOrder.getCheckOutDate() != null, "recordDate", itripHotelOrder.getCheckOutDate());
        //根据酒店id 房间id 时间筛选出所选房间时间段库存
        List<ItripHotelTempStore> hotelList = iItripHotelTempStoreService.list(wrapper);
        //判断输入数和库存比对
        for (ItripHotelTempStore ih :
                hotelList) {
            if (ih.getStore() < itripHotelOrder.getCount()) {
                return DtoUtil.returnError("100507  ", "库存不足", "");
            }
        }
        //生成支付信息表订单
        ItripTradeEnds ite = new ItripTradeEnds();
        //生成订单号
        StringBuffer sb = new StringBuffer();
        sb.append("D1000001");//固定前缀
        sb.append(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
        sb.append(MD5.getMd5(itripHotelOrder.getHotelName(), 6));
        System.out.println("处理好的密文订单号" + sb);
        ite.setOrderNo(sb.toString());
        ite.setFlag(1);
        boolean save = iItripTradeEndsService.save(ite);
        if (!save) {
            return DtoUtil.returnError("100505", "生成订单失败", "");
        }
        //根据订单号查自增id
        QueryWrapper<ItripTradeEnds> wrapper2 = new QueryWrapper<>();
        wrapper2.eq("orderNo", sb.toString());
        Long id = iItripTradeEndsService.getOne(wrapper2).getId();
        System.out.println("获取到的支付订单自增id是" + id);

        //处理酒店订单表
        //获取token字符串
        StringBuffer token = new StringBuffer();
        token.append(request.getHeader("token"));
        //根据token字符串查询用户id
        String userCode = token.substring(token.indexOf("-") + 1);
        userCode = userCode.substring(0, userCode.indexOf("-"));
        System.out.println("获取到的用户名为" + userCode);
        //根据用户名查询id
        QueryWrapper<ItripUser> wrapper3 = new QueryWrapper<>();
        wrapper3.eq("userCode", userCode);
        Long userId = itripUserService.getOne(wrapper3).getId();
        System.out.println("生成订单的用户id为" + userId);

        //添加酒店订单表信息
        itripHotelOrder.setUserId(userId);
        itripHotelOrder.setOrderNo(sb.toString());
        //入住天数
        Long timeDay = (itripHotelOrder.getCheckOutDate().getTime() - itripHotelOrder.getCheckInDate().getTime()) / (24 * 60 * 60 * 1000);
        System.out.println("入住天数" + timeDay);
        itripHotelOrder.setBookingDays(Integer.valueOf(String.valueOf(timeDay)));
        itripHotelOrder.setOrderStatus(0);
        //支付金额
        QueryWrapper<ItripHotelRoom> wrapper4 = new QueryWrapper<>();
        wrapper4.eq("id", itripHotelOrder.getRoomId());
        ItripHotelRoom roomprice = iItripHotelRoomService.getOne(wrapper4);
        System.out.println("酒店价格是" + roomprice.getRoomPrice());
        itripHotelOrder.setPayAmount(BigDecimal.valueOf(roomprice.getRoomPrice().doubleValue() * itripHotelOrder.getCount().intValue()));
        System.out.println("酒店价格是2" + itripHotelOrder.getPayAmount());
        itripHotelOrder.setPayType(2);
        //住户处理
        StringBuffer userLinks = new StringBuffer();
        for (int i = 0; i < linkUser.size(); i++) {
            userLinks.append(linkUser.get(i).getLinkUserName());
            if (i != linkUser.size() - 1) {
                userLinks.append(",");
            }
        }
        System.out.println("处理好后的住户信息：" + userLinks);
        itripHotelOrder.setLinkUserName(userLinks.toString());
        itripHotelOrder.setCreationDate(new Date());
        itripHotelOrder.setCreatedBy(userId);

        //处理完成，打印预览
        System.out.println("》》》处理完成，打印预览" + itripHotelOrder);

        boolean save1 = iItripHotelOrderService.save(itripHotelOrder);
        //获取酒店订单自增id
        QueryWrapper<ItripHotelOrder> wrapper8 = new QueryWrapper<>();
        wrapper8.eq("orderNo", sb.toString());
        Long hotelOrderid = iItripHotelOrderService.getOne(wrapper8).getId();
        System.out.println("获取到的支付订单自增id是" + id);
        ite.setId(hotelOrderid);
        if (!save1) {
            return DtoUtil.returnError("100505", "生成订单失败", "");
        }

        Map<String, String> map = new HashMap<>();
        map.put("orderNo", sb.toString());
        map.put("id", hotelOrderid.toString());

        return DtoUtil.returnSuccess("生成订单成功！", map);
    }

    @GetMapping("/api/alipay/refreshQrcode/{orderNo}")
    public Dto queryhotelpolicy(@PathVariable("orderNo") String orderNo) {
        System.out.println(">>>此接口用来刷新二维码");
        System.out.println("orderNo：" + orderNo);

        //调用RSA签名方式
        AlipayClient client = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGNTYPE);

        //获取请求
        AlipayTradePrecreateRequest alipay_request = new AlipayTradePrecreateRequest();

        // 封装请求支付信息
        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();

        model.setOutTradeNo(orderNo);
        model.setSubject("酒店订单");
        //根据订单号获取价格
        QueryWrapper<ItripHotelOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("orderNo", orderNo);
        ItripHotelOrder one = iItripHotelOrderService.getOne(wrapper);
        model.setTotalAmount(String.valueOf(one.getPayAmount()));
        model.setBody("酒店订单");

        //将封装好的支付信息放入请求
        alipay_request.setBizModel(model);

        // 设置异步通知地址
        alipay_request.setNotifyUrl(AlipayConfig.notify_url);

        try {
            // 调用SDK, 获取响应
            AlipayTradePrecreateResponse response = client.execute(alipay_request);
            System.out.println("测试:" + response.getQrCode());
            System.out.println("测试:" + response.getCode());
            //获取订单编号
            QueryWrapper<ItripTradeEnds> wrapper2 = new QueryWrapper<>();
            wrapper2.eq("orderNo", orderNo);
            ItripTradeEnds one2 = iItripTradeEndsService.getOne(wrapper2);
            Code code = new Code(response.getQrCode(), orderNo, one2.getId().toString());

            return DtoUtil.returnSuccess("订单待支付", code);
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return DtoUtil.returnSuccess("订单支付失败");
        }

    }


    @GetMapping("/api/alipay/queryorderstatus/{orderNo}")
    @ResponseBody
    public Dto queryorderstatus(@PathVariable("orderNo") String orderNo) {
        System.out.println(">>>此接口是使用前端定时器来处理，3秒一次, 向后台发送查询请求");
        System.out.println("orderNo：" + orderNo);
        //获取支付宝订单号
        QueryWrapper<ItripHotelOrder> wrapper99 = new QueryWrapper<>();
        wrapper99.eq("orderNo", orderNo);

        ///
        AlipayClient client = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGNTYPE);

        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();

        Map<String, Object> param = new HashMap<>();
        param.put("out_trade_no", orderNo);
        param.put("trade_no", null);
        param.put("query_options", new String[]{"trade_settle_info"});
        request.setBizContent(JSONObject.toJSONString(param));

        try {
            AlipayTradeQueryResponse response = client.execute(request);
            //获取支付宝生成的订单号,并存入数据库
            String outTradeNo = response.getTradeNo();
            QueryWrapper<ItripHotelOrder> wrapper9 = new QueryWrapper<>();
            wrapper9.eq("orderNo", orderNo);
            ItripHotelOrder hotelOrder = iItripHotelOrderService.getOne(wrapper9);
            hotelOrder.setTradeNo(outTradeNo);
            boolean b = iItripHotelOrderService.updateById(hotelOrder);

            System.out.println("判断请求是否成功" + response.getCode());
            System.out.println("判断支付信息" + response.getTradeStatus());
            //判断请求是否成功
            if(response.getTradeStatus().equals("TRADE_SUCCESS")) {
                //支付成功
                hotelOrder.setOrderStatus(2);
                boolean c = iItripHotelOrderService.updateById(hotelOrder);
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        ///

        QueryWrapper<ItripHotelOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("orderNo", orderNo);
        ItripHotelOrder one = iItripHotelOrderService.getOne(wrapper);
        //0：待支付 1:已取消 2:支付成功 3:已消费 4：已点评
        if (one.getOrderStatus() == 1) {
            return DtoUtil.returnError("10001", "订单待支付", "");
        } else if (one.getOrderStatus() == 2) {
            return DtoUtil.returnSuccess("支付成功", "", "10002");
        } else if (one.getOrderStatus() == 3) {
            return DtoUtil.returnError("10003", "支付失败", "");
        } else {
            return DtoUtil.returnError("10004", "系统异常", "");
        }

    }

}
